<template>
  <div ref="table" :id="id" class="advanced-table">
    <a-spin :spinning="loading">
      <div :class="['header-bar', size]">
        <div class="title">
          <template v-if="title">{{ title }}</template>
          <slot v-else-if="$slots.title" name="title"></slot>
          <template v-else>高级表格</template>
        </div>
        <div class="search">
          <search-area
            :format-conditions="formatConditions"
            @change="onSearchChange"
            :columns="columns"
          >
            <template :slot="slot" v-for="slot in slots">
              <slot :name="slot"></slot>
            </template>
          </search-area>
        </div>
        <div class="actions">
          <a-tooltip title="刷新">
            <a-icon
              @click="refresh"
              class="action"
              :type="loading ? 'loading' : 'reload'"
            />
          </a-tooltip>
          <action-size v-model="sSize" class="action" />
          <a-tooltip title="列配置">
            <action-columns
              :columns="columns"
              @reset="onColumnsReset"
              class="action"
            >
              <template :slot="slot" v-for="slot in slots">
                <slot :name="slot"></slot>
              </template>
            </action-columns>
          </a-tooltip>
          <a-tooltip title="全屏">
            <a-icon
              @click="toggleScreen"
              class="action"
              :type="fullScreen ? 'fullscreen-exit' : 'fullscreen'"
            />
          </a-tooltip>
        </div>
      </div>
      <a-table
        v-bind="{
          ...$props,
          columns: visibleColumns,
          title: undefined,
          loading: false,
        }"
        :size="sSize"
        @expandedRowsChange="onExpandedRowsChange"
        @change="onChange"
        @expand="onExpand"
      > 
        <template
          slot-scope="text, record, index"
          :slot="slot"
          v-for="slot in scopedSlots"
        >
          <slot :name="slot" v-bind="{ text, record, index }"></slot>
        </template>
        <template :slot="slot" v-for="slot in slots">
          <slot :name="slot"></slot>
        </template>
        <template
          slot-scope="record, index, indent, expanded"
          :slot="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"
        >
          <slot
            v-bind="{ record, index, indent, expanded }"
            :name="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"
          ></slot>
        </template>
      </a-table>
    </a-spin>
  </div>
</template>

<script>
import ActionSize from "@/components/table/advance/ActionSize";
import ActionColumns from "@/components/table/advance/ActionColumns";
import SearchArea from "@/components/table/advance/SearchArea";
export default {
  name: "AdvanceTable",
  components: { SearchArea, ActionColumns, ActionSize },
  props: {
    // 表格元素的 table-layout 属性，设为 fixed 表示内容不会影响列的布局	- | 'auto' | 'fixed'	无 固定表头/列或使用了 column.ellipsis 时，默认值为 fixed
    tableLayout: String,
    // 表格边框 默认 false
    bordered: Boolean,
    // 指定树形结构的列名	string[]
    childrenColumnName: { type: String, default: "children" },
    // 绑定列
    columns: Array,
    // 覆盖默认的 table 元素	object
    components: Object,
    // 数据源
    dataSource: Array,
    // 初始时，是否展开所有行	boolean 默认false
    defaultExpandAllRows: Array[String],
    // 默认展开的行	string[]
    expandedRowKeys: Array[String],
    // 额外的展开行
    expandedRowRender: Function,
    // 自定义展开图标
    expandIcon: Function,
    // 通过点击行来展开子行
    expandRowByClick: Boolean,
    // 展开的图标显示在哪一列，如果没有 rowSelection，默认显示在第一列，否则显示在选择框后面
    expandIconColumnIndex: Number,
    // 表格尾部 Function(currentPageData)|slot-scope
    footer: Function,
    // 展示树形数据时，每层缩进的宽度，以 px 为单位 number 默认 15
    indentSize: Number,
    // 页面是否加载中 默认 false
    loading: Boolean,
    // 默认文案设置，目前包括排序、过滤、空数据文案 filterConfirm: '确定' filterReset: '重置' emptyText: '暂无数据'
    locale: Object,
    // 分页器，参考配置项或 pagination文档，设为 false 时不展示和进行分页
    pagination: [Object, Boolean],
    // 表格行的类名
    rowClassName: Function,
    // 表格行 key 的取值，可以是字符串或一个函数
    rowKey: [String, Function],
    // 列表项是否可选择
    rowSelection: Object,
    // 设置横向或纵向滚动，也可用于指定滚动区域的宽和高，建议为 x 设置一个数字，如果要设置为 true，需要配合样式 .ant-table td { white-space: nowrap; }
    scroll: Object,
    // 是否显示表头	boolean	true
    showHeader: { type: Boolean, default: true },
    // 表格大小	default | middle | small	default
    size: String,
    // 表格标题	Function(currentPageData)|slot-scope
    title: String,
    // 设置头部行属性	Function(column, index)
    customHeaderRow: Function,
    // 设置行属性	Function(record, index)
    customRow: Function,
    // 设置表格内各类浮层的渲染节点，如筛选菜单	(triggerNode) => HTMLElement
    getPopupContainer: Function,
    // 数据渲染前可以再次改变，一般用户空数据的默认配置，可以通过 ConfigProvider 全局统一配置
    transformCellText: Function,
    // 是否格式化搜索条件的值，格式化规则参考 Search 配置。false：取搜索输入控件的原值 true：取搜索输入控件格式化后的值
    formatConditions: Boolean,
  },
  provide() {
    return {
      table: this,
    };
  },
  data() {
    return {
      id: `${new Date().getTime()}-${Math.floor(Math.random() * 10)}`,
      sSize: this.size || "small", // default
      fullScreen: false,
      conditions: {},
    };
  },
  computed: {
    slots() {
      return Object.keys(this.$slots).filter((slot) => slot !== "title");
    },
    scopedSlots() {
      return Object.keys(this.$scopedSlots).filter(
        (slot) => slot !== "expandedRowRender" && slot !== "title"
      );
    },
    visibleColumns() {
      return this.columns.filter((col) => col.visible);
    },
  },
  created() {
    this.addListener();
  },
  beforeDestroy() {
    this.removeListener();
  },
  methods: {
    refresh() {
      this.$emit("refresh", this.conditions);
    },
    onSearchChange(conditions, searchOptions) {
      this.conditions = conditions;
      this.$emit("search", conditions, searchOptions);
    },
    toggleScreen() {
      if (this.fullScreen) {
        this.outFullScreen();
      } else {
        this.inFullScreen();
      }
    },
    inFullScreen() {
      const el = this.$refs.table;
      el.classList.add("beauty-scroll");
      if (el.requestFullscreen) {
        el.requestFullscreen();
        return true;
      } else if (el.webkitRequestFullScreen) {
        el.webkitRequestFullScreen();
        return true;
      } else if (el.mozRequestFullScreen) {
        el.mozRequestFullScreen();
        return true;
      } else if (el.msRequestFullscreen) {
        el.msRequestFullscreen();
        return true;
      }
      this.$message.warn("对不起，您的浏览器不支持全屏模式");
      el.classList.remove("beauty-scroll");
      return false;
    },
    outFullScreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
      this.$refs.table.classList.remove("beauty-scroll");
    },
    onColumnsReset(conditions) {
      this.$emit("reset", conditions);
    },
    onExpandedRowsChange(expandedRows) {
      this.$emit("expandedRowsChange", expandedRows);
    },
    onChange(pagination, filters, sorter, options) {
      this.$emit("change", pagination, filters, sorter, options);
    },
    onExpand(expanded, record) {
      this.$emit("expand", expanded, record);
    },
    addListener() {
      document.addEventListener("fullscreenchange", this.fullScreenListener);
      document.addEventListener(
        "webkitfullscreenchange",
        this.fullScreenListener
      );
      document.addEventListener("mozfullscreenchange", this.fullScreenListener);
      document.addEventListener("msfullscreenchange", this.fullScreenListener);
    },
    removeListener() {
      document.removeEventListener("fullscreenchange", this.fullScreenListener);
      document.removeEventListener(
        "webkitfullscreenchange",
        this.fullScreenListener
      );
      document.removeEventListener(
        "mozfullscreenchange",
        this.fullScreenListener
      );
      document.removeEventListener(
        "msfullscreenchange",
        this.fullScreenListener
      );
    },
    fullScreenListener(e) {
      if (e.target.id === this.id) {
        this.fullScreen = !this.fullScreen;
      }
    },
  },
};
</script>

<style scoped lang="less">
.advanced-table {
  overflow-y: auto;
  background-color: @component-background;
  .header-bar {
    padding: 16px 24px;
    display: flex;
    align-items: center;
    border-radius: 4px;
    transition: all 0.3s;
    &.middle {
      padding: 12px 16px;
    }
    &.small {
      padding: 8px 12px;
      border: 1px solid @border-color;
      border-bottom: 0;
      .title {
        font-size: 16px;
      }
    }
    .title {
      transition: all 0.3s;
      font-size: 18px;
      color: @title-color;
      font-weight: 700;
    }
    .search {
      flex: 1;
      text-align: right;
      margin: 0 24px;
    }
    .actions {
      text-align: right;
      font-size: 17px;
      color: @text-color;
      .action {
        margin: 0 8px;
        cursor: pointer;
        &:hover {
          color: @primary-color;
        }
      }
    }
  }
}

.ant-table-small > .ant-table-content > .ant-table-body{
  margin: 0 !important;
}
</style>
